package com.admin.system.modules.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.admin.common.utils.PageResult;
import com.admin.common.utils.PageUtil;
import com.admin.core.dto.RoleQueryDTO;
import com.admin.core.entity.SysRole;
import com.admin.core.entity.SysRoleDept;
import com.admin.core.entity.SysRoleMenu;
import com.admin.core.entity.SysUserRole;
import com.admin.core.mapper.RoleDeptMapper;
import com.admin.core.mapper.RoleMapper;
import com.admin.core.mapper.RoleMenuMapper;
import com.admin.core.mapper.UserRoleMapper;
import com.admin.oauth.util.LoginUserUtil;
import com.admin.system.modules.system.service.RoleService;
import com.admin.system.util.DataScopeWrapperUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author sq-lan
 */
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, SysRole> implements RoleService {

    private final RoleDeptMapper roleDeptMapper;
    private final RoleMenuMapper roleMenuMapper;
    private final UserRoleMapper userRoleMapper;

    @Override
    public PageResult<SysRole> paging(RoleQueryDTO dto) {
        PageHelper.startPage(dto.getCurrent(), dto.getSize());
        List<SysRole> list = this.list(dto);
        // 查询关联的菜单、部门
        /*for (SysRole entry : list) {
            List<SysMenu> menus = roleMenuMapper.listMenuByRoleId(entry.getId());
            entry.setMenus(menus);

            if (DataScopeEnum.CUSTOMIZE.getValue().equals(entry.getDataScope())) {
                List<SysDept> deps = roleDeptMapper.listDeptByRoleId(entry.getId());
                entry.setDepts(deps);
            }
        }*/
        return PageUtil.toPageHelper(list);
    }

    @Override
    public List<SysRole> list(RoleQueryDTO dto) {
        LambdaQueryWrapper<SysRole> wrapper = createWrapper(dto);
        DataScopeWrapperUtil.dataScope(wrapper);
        return this.list(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysRole entity) {
        entity.setDeptId(LoginUserUtil.user().getDeptId());
        this.save(entity);
        // 关联部门数据
        if (CollectionUtil.isNotEmpty(entity.getDepartments())) {
            roleDeptMapper.insertData(entity.getId(), entity.getDepartments());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modify(SysRole entity) {
        SysRole role = new SysRole();
        role.setId(entity.getId());
        role.setName(entity.getName());
        role.setDescription(entity.getDescription());
        role.setDataScope(entity.getDataScope());
        this.updateById(role);
        // 删除关联部门数据
        roleDeptMapper.delete(Wrappers.<SysRoleDept>lambdaQuery().eq(SysRoleDept::getRoleId, entity.getId()));
        // 更新部门数据
        if (CollectionUtil.isNotEmpty(entity.getDepartments())) {
            roleDeptMapper.insertData(entity.getId(), entity.getDepartments());
        }
    }

    @Override
    public void updateMenu(SysRole role) {
        // 更新菜单
        roleMenuMapper.delete(Wrappers.<SysRoleMenu>lambdaQuery().eq(SysRoleMenu::getRoleId, role.getId()));
        if (CollUtil.isNotEmpty(role.getMenus())) {
            roleMenuMapper.insertData(role.getId(), role.getMenus());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(Set<Integer> ids) {
        removeByIds(ids);
        // 删除角色部门关联数据、角色菜单关联数据
        roleDeptMapper.delete(Wrappers.<SysRoleDept>lambdaQuery().in(SysRoleDept::getRoleId, ids));
        roleMenuMapper.delete(Wrappers.<SysRoleMenu>lambdaQuery().in(SysRoleMenu::getRoleId, ids));
    }

    @Override
    public List<SysRole> listByUsersId(int userId) {
        List<SysUserRole> roles = userRoleMapper.selectList(Wrappers.<SysUserRole>lambdaQuery().select(SysUserRole::getRoleId).eq(SysUserRole::getUserId, userId));
        if (CollUtil.isEmpty(roles)) {
            return Collections.emptyList();
        }
        List<Integer> roleIds = roles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        return this.list(Wrappers.<SysRole>lambdaQuery().select(SysRole::getId, SysRole::getName, SysRole::getDataScope).in(SysRole::getId, roleIds));
    }

    private LambdaQueryWrapper<SysRole> createWrapper(RoleQueryDTO dto) {
        LambdaQueryWrapper<SysRole> wrapper = Wrappers.lambdaQuery();
        if (org.springframework.util.StringUtils.hasText(dto.getBlurry())) {
            wrapper.and(w -> w.like(SysRole::getName, dto.getBlurry()).or().like(SysRole::getDescription, dto.getBlurry()));
        }
        if (dto.getCreateTime() != null && !dto.getCreateTime().isEmpty()) {
            wrapper.between(SysRole::getCreateTime, dto.getCreateTime().get(0), dto.getCreateTime().get(1));
        }
        return wrapper;
    }

}
